package com.rockcent.mall.lib.repository;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.rockcent.common.common.PageResult;
import com.rockcent.common.common.SQLListDoing;
import com.rockcent.common.common.SQLPageDoing;
import com.rockcent.common.utils.RDateUtils;
import com.rockcent.mall.lib.domain.enumclass.FundTransactionFlow;
import com.rockcent.mall.lib.domain.enumclass.MallFundFlowTransactionType;
import com.rockcent.mall.lib.domain.enumclass.PaymentMethod;
import com.rockcent.mall.lib.dto.MallFundFlowDto;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Repository;

import java.util.Arrays;
import java.util.List;


/**
 * Created by DK on 16/11/8.
 */
@Repository
public class MallFundFlowRepositoryImpl implements MallFundFlowRepositoryCustom{
    private static final Logger log = LoggerFactory.getLogger(MallFundFlowRepositoryImpl.class);

    @Autowired
    private NamedParameterJdbcTemplate jdbcTemplate;

    @Autowired
    private ObjectMapper objectMapper;


    @Override
    public PageResult<MallFundFlowDto> findMallFundFlowPage(String transactionType, String transactionFlow, String paymentMethod, String beginDate, String endDate, Double operationAmount, String mallOrderNum, Long mallId, PageResult pageResult) {
        SQLPageDoing<MallFundFlowDto> doing = (sql, fields, params, map) -> {
            sql.append("select %s from mall_fund_flow mff where 1=1 ");

            if (MallFundFlowTransactionType.ALL != MallFundFlowTransactionType.valueOf(transactionType)) {
                if (MallFundFlowTransactionType.F_PAYMENT_SUCCESS_FROZEN == MallFundFlowTransactionType.valueOf(transactionType)) {
                    sql.append(" AND mff.transaction_type in (:transactionType)");
                    params.put("transactionType", Arrays.asList(MallFundFlowTransactionType.F_PAYMENT_SUCCESS_FROZEN.toString(), MallFundFlowTransactionType.F_BALANCE_SUCCESS_FROZEN.toString(), MallFundFlowTransactionType.F_CASH_COUPON_SUCCESS_FROZEN.toString()));
                }else {
                    sql.append(" AND mff.transaction_type = :transactionType");
                    params.put("transactionType", transactionType);
                }
            }else {
                sql.append(" AND mff.transaction_type not in (:transactionType)");
                params.put("transactionType", Arrays.asList(MallFundFlowTransactionType.F_CASH_COUPON_SURPLUS_SUCCESS_FROZEN_EXPEND.toString(), MallFundFlowTransactionType.F_CASH_COUPON_SURPLUS_SUCCESS_INCOME.toString()));
            }

            if (FundTransactionFlow.ALL != FundTransactionFlow.valueOf(transactionFlow)) {
                sql.append(" AND mff.transaction_flow = :transactionFlow");
                params.put("transactionFlow", transactionFlow);
            }

            if (PaymentMethod.ALL != PaymentMethod.valueOf(paymentMethod)) {
                sql.append(" AND mff.payment_method = :paymentMethod");
                params.put("paymentMethod", paymentMethod);
            }

            if (operationAmount != null && operationAmount != 0.0) {
                sql.append(" AND mff.operation_amount = :operationAmount");
                params.put("operationAmount", operationAmount);
            }

            if (StringUtils.isNotBlank(mallOrderNum)) {
                sql.append(" AND mff.mall_order_num LIKE :mallOrderNum");
                params.put("mallOrderNum", "%" + mallOrderNum + "%");
            }
            if (StringUtils.isNotBlank(beginDate) && StringUtils.isNotBlank(endDate)) {
                sql.append(" AND mff.date_created < :endDate AND mff.date_created > :beginDate");
                params.put("beginDate", RDateUtils.beforeDateStr(beginDate, 0));
                params.put("endDate", RDateUtils.afterDateStr(endDate, 1));
            }
            sql.append(" AND mff.mall_id = :mallId");
            sql.append(" AND mff.transaction_flow != 'SPLIT' and  mff.is_delete <>'YES'");
            params.put("mallId", mallId);
            sql.append(" ORDER BY mff.date_created desc");
            fields.append("mff.*");

        };
        return doing.go(pageResult, MallFundFlowDto.class, objectMapper, jdbcTemplate, log);
    }

    @Override
    public List<MallFundFlowDto> findMallFundFlowExport(String transactionType, String transactionFlow, String paymentMethod, String beginDate, String endDate, Double operationAmount, String mallOrderNum, Long mallId) {
        SQLListDoing<MallFundFlowDto> doing = (sql, fields, params, typeReferenceMap) -> {
            sql.append("select %s from mall_fund_flow mff where 1=1 ");
            if (MallFundFlowTransactionType.ALL != MallFundFlowTransactionType.valueOf(transactionType)) {
                sql.append(" AND mff.transaction_type = :transactionType");
                params.put("transactionType", transactionType);
            }

            if (FundTransactionFlow.ALL != FundTransactionFlow.valueOf(transactionFlow)) {
                sql.append(" AND mff.transaction_flow = :transactionFlow");
                params.put("transactionFlow", transactionFlow);
            }

            if (PaymentMethod.ALL != PaymentMethod.valueOf(paymentMethod)) {
                sql.append(" AND mff.payment_method = :paymentMethod");
                params.put("paymentMethod", paymentMethod);
            }

            if (StringUtils.isNotBlank(mallOrderNum)) {
                sql.append(" AND mff.mall_order_num LIKE :mallOrderNum");
                params.put("mallOrderNum", "%" + mallOrderNum + "%");
            }

            if (operationAmount != null && operationAmount != 0.0) {
                sql.append(" AND mff.operation_amount = :operationAmount");
                params.put("operationAmount", operationAmount);
            }

            if(StringUtils.isNotBlank(beginDate)){
                sql.append(" AND mff.date_created > :beginDate");
                params.put("beginDate", RDateUtils.beforeDateStr(beginDate, 0));
            }
            if(StringUtils.isNotBlank(endDate)){
                sql.append(" AND mff.date_created < :endDate");
                params.put("endDate", RDateUtils.afterDateStr(endDate, 1));
            }
            sql.append(" AND mff.mall_id = :mallId");
            sql.append(" AND mff.transaction_flow != 'SPLIT' and  mff.is_delete <>'YES'");
            params.put("mallId", mallId);
            sql.append(" ORDER BY mff.date_created asc");
            fields.append("mff.*, mff.date_created createDate");
        };
        return doing.go(MallFundFlowDto.class, objectMapper, jdbcTemplate, log);
    }
}
